package com.jml.springmvc.手写008.servlet.web;

import com.jml.springmvc.手写008.annotation.ComponentScan;
import com.jml.springmvc.手写008.annotation.Controller;
import com.jml.springmvc.手写008.annotation.RequestMapping;
import com.jml.springmvc.手写008.config.SpringMvcConfig;
import com.jml.springmvc.手写008.handler.HandlerMethod;
import com.jml.utils.ReflexUtils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;


public class RequestMappingHandlerMapping {
	
	// 在初始化我们SpringMVC Bean对象、url与方法关联存放到Map集合中
	private Map<String, HandlerMethod> registry = new HashMap<String, HandlerMethod>();
	
	public void initHandlerMappings() {
		ComponentScan componentScan = SpringMvcConfig.class.getDeclaredAnnotation(ComponentScan.class);
		String springmvcPackage = componentScan.value();
		if (StringUtils.isEmpty(springmvcPackage)) {
			return;
		}
		// 1. 使用java反射机制 查找该包下controller 有那些控制类
		Set<Class<?>> classes = ReflexUtils.getClasses(springmvcPackage);
		// 2. 循环遍历每个类 只要有加上
		for (Class<?> classInfo : classes) {
			// 3.判断类上是否有加上我们的控制注解
			Controller controller = classInfo.getDeclaredAnnotation(Controller.class);
			if (controller == null) {
				continue;
			}
			// 4.遍历控制层类中方法是否有加上RequestMapping
			Method[] declaredMethods = classInfo.getDeclaredMethods();
			for (Method methodInfo : declaredMethods) {
				RequestMapping requestMapping = methodInfo.getDeclaredAnnotation(RequestMapping.class);
				if (requestMapping == null) {
					continue;
				}
				String url = requestMapping.value();
				// 存放到hashMap集合中 key url value: Method
				registry.put(url, new HandlerMethod(newInstance(classInfo), methodInfo));
			}
		}
	}
	
	private Object newInstance(Class classInfo) {
		try {
			Object value = classInfo.newInstance();
			return value;
		} catch (Exception e) {
			return null;
		}
	}
	
	public HandlerMethod getHandlerMethod(String url) {
		return registry.get(url);
	}
}
